package cn.com.dhcc.turbo.web.controller.monitor;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.com.dhcc.app.core.CM;
import cn.com.dhcc.app.core.base.BaseController;
import cn.com.dhcc.app.core.exception.ServiceException;
import cn.com.dhcc.app.core.handler.modulehandler.WhereCondition;
import cn.com.dhcc.app.core.handler.modulehandler.valuebean.BetweenValue;
import cn.com.dhcc.app.core.handler.pagerhandler.Pager;
import cn.com.dhcc.app.core.handler.pagerhandler.PagerData;
import cn.com.dhcc.app.core.service.Log;
import cn.com.dhcc.app.core.service.Log.LOGTYPE;
import cn.com.dhcc.app.core.util.CollectionUtil;
import cn.com.dhcc.app.core.util.DTUtil;
import cn.com.dhcc.app.core.util.JsonUtil;
import cn.com.dhcc.app.core.util.StrUtil;
import cn.com.dhcc.app.core.util.XstreamUtil;
import cn.com.dhcc.app.pub.core.annotation.TurboMenu;
import cn.com.dhcc.app.pub.core.annotation.TurboMenu.LEAF_MENU;
import cn.com.dhcc.app.pub.core.consts.AppConst;
import cn.com.dhcc.app.pub.core.consts.AppIocBean;
import cn.com.dhcc.app.pub.core.consts.NodeInfoParam;
import cn.com.dhcc.app.pub.core.tag.AppTagEl;
import cn.com.dhcc.app.pub.core.util.ZipUtil;
import cn.com.dhcc.turbo.entity.api.Posthead;
import cn.com.dhcc.turbo.entity.api.ProcessInfo;
import cn.com.dhcc.turbo.entity.api.RouteLog;
import cn.com.dhcc.turbo.entity.exch.SendCmData;
import cn.com.dhcc.turbo.entity.registry.NodeInfo;
import cn.com.dhcc.turbo.entity.sysmgr.UserInfo;
import cn.com.dhcc.turbo.entity.sysmgr.UserInfo.SL_AUTH_FLAG;
import cn.com.dhcc.turbo.service.exch.cmdata.CmDataExchangeLifecycle;
import cn.com.dhcc.turbo.service.exch.cmdata.CmDataExchangeLifecycleImpl;
import cn.com.dhcc.turbo.service.exch.cmdata.SendCmDataService;
import cn.com.dhcc.turbo.service.registry.BaseInfoService;
import cn.com.dhcc.turbo.service.registry.NodeInfoService;

@Controller
@RequestMapping("/monitor")
@TurboMenu(belongToMenu=LEAF_MENU.SEND_CM_DATA)
public class SendCmDataController extends BaseController {
	@SuppressWarnings("deprecation")
	private static Logger logger = Log.getExistLogger(LOGTYPE.SAI);

	@Autowired
	private SendCmDataService cmDataService;
    @Autowired
    private NodeInfoService nodeInfoService;
    @Autowired
    private BaseInfoService baseInfoService;
	@RequestMapping(value = "/send_cm_data_list")
	public String list(
			Model model, 
			Pager pager, 
			HttpServletRequest request,
			String sendNodecode, 
			String recvNodecode, 
			String sendAdapterCode,
			String msgType,
			String sendStatus,
			String crossNode,
			String crossNet,
			String notifyStatus,
			String startCreated, 
			String endCreated, 
			String orderName, 
			String order) {
		try {
			UserInfo userInfo = (UserInfo)BaseController.getCurrentUserInfo(request.getSession());
			boolean isSysUser = userInfo.getSlAuthFlag().equalsIgnoreCase(SL_AUTH_FLAG.SYS_USER.getCode());
			NodeInfo localNode=nodeInfoService.getLocalNode();
			
			WhereCondition searchData = new WhereCondition();
			searchData.where()
			.leftBracket()
			.notEq("msg_type", AppConst.MsgType.SUB_MSG.value())
			.and().eq("SEND_NODECODE", localNode.getNodeCode())
			.or().notEq("SEND_NODECODE", localNode.getNodeCode())
			.rightBracket();
			
			List<Map<String,String>> sendNodeList=new ArrayList<Map<String,String>>();
			List<Map<String,String>> sendAdapterList=new ArrayList<Map<String,String>>();
			if (StrUtil.isNotBlank(sendNodecode)) {
				searchData.and().like("send_nodecode", sendNodecode);
			}else if (isSysUser) {
				searchData.and().like("send_nodecode", baseInfoService.getCurrentNodeInfo().getNodeCode());
				searchData.and().like("send_adaptorcode", userInfo.getUserName());
				
				//默认选择项
				Map<String,String> sendNodeMap=new HashMap<String, String>();
				sendNodeMap.put("code", localNode.getNodeCode());
				sendNodeMap.put("name", localNode.getNodeName());
				sendNodeList.add(sendNodeMap);
				//默认选择项
				Map<String,String> sendAdapterMap=new HashMap<String, String>();
				sendAdapterMap.put("code", userInfo.getUserName());
				sendAdapterMap.put("name", AppTagEl.adaptorName(userInfo.getUserName()));
				sendAdapterList.add(sendAdapterMap);
			}
			
			if (StrUtil.isNotBlank(sendAdapterCode)) {
				searchData.and().like("send_adaptorcode", sendAdapterCode);
			}
			if (StrUtil.isNotBlank(recvNodecode)) {
				searchData.and().like("recv_nodecode", recvNodecode);
			}
			
			if (StrUtil.isNotBlank(notifyStatus)) {
				searchData.and().like("NOTIFY_STATUS", notifyStatus);
			}
			if (StrUtil.isNotBlank(msgType)) {
				searchData.and().like("msg_type", msgType);
			}
			
			if (StrUtil.isNotBlank(crossNode)) {
				searchData.and().eq("cross_node", crossNode);
			}
			if (StrUtil.isNotBlank(crossNet)) {
				if ("0".equals(crossNet)) {
					searchData.and().eq("cross_net", crossNet);
				}else{
					searchData.and().notEq("cross_net", "0");
				}
			}
			//这里对发生中的状态进行了处理，把本地发送和远程发送都看做为发送中
			if (StrUtil.isNotBlank(sendStatus)) {
				if (AppConst.SendStatus.LOCAL_SENDING.value().equals(sendStatus)) {
					searchData.and().leftBracket()
								.eq("send_status", sendStatus)
								.or()
								.eq("send_status", AppConst.SendStatus.REMOTE_SENDING.value())
								.rightBracket();
				} else {
					searchData.and().eq("send_status", sendStatus);
				}
			}
			//时间范围从那天到那天
			if (StrUtil.isNotBlank(startCreated) && StrUtil.isNotBlank(endCreated)) {
				searchData.and().between("created", new BetweenValue(DTUtil.toDateTime(startCreated) , DTUtil.toDateTime(endCreated)));
			}

			//时间范围，大于等于某天
			if (StrUtil.isNotBlank(startCreated) && StrUtil.isBlank(endCreated)) {	
				searchData.and().between("created", new BetweenValue(DTUtil.toDateTime(startCreated), null, true, false));
			}

			//时间范围，小于等于某天
			if (StrUtil.isBlank(startCreated) && StrUtil.isNotBlank(endCreated)) {	
				searchData.and().between("created", new BetweenValue(null, DTUtil.toDateTime(endCreated), false, true));
			}
			
			if (StrUtil.isNotBlank(orderName)) {
				searchData.orderBy(orderName + " " + order);
			} else {
				searchData.orderBy("created  desc");
			}
			PagerData<SendCmData> datas = cmDataService.getPagerList(pager, searchData);
			List<SendCmData> dataList = datas.getDatas();
			if(CollectionUtil.hasElement(dataList)){
				for (SendCmData sendCmData : dataList) {
					if (AppConst.MsgType.GROUP_MSG.value().equals(sendCmData.getMsgType())) {
						sendCmData.setSubMsgNum(cmDataService.countSubMsg(sendCmData.getId()));
					}else{
						sendCmData.setSubMsgNum(1);
					}
				}
			}
			model.addAttribute(DATA_KEY, dataList);
			model.addAttribute("localNode",localNode );
			
			
			if (isSysUser && cmDataService.getSendNodeList().size()<=0) {
				model.addAttribute("send_node_list", sendNodeList);
			}else{
				model.addAttribute("send_node_list", cmDataService.getSendNodeList());
			}
			
			if (isSysUser && cmDataService.getSendAdapterList().size()<=0) {
				model.addAttribute("send_adapter_list", sendAdapterList);
			}else{
				model.addAttribute("send_adapter_list", cmDataService.getSendAdapterList());
			}
			
			model.addAttribute("isSysUser", isSysUser);
			model.addAttribute("recv_node_list", cmDataService.getRecvNodeList());
			model.addAttribute("send_status_list", AppConst.SendStatus.values());
			model.addAttribute("notify_status_list", AppConst.NotifyStatus.values());
			setTotoal(model, datas.getTotal());
			return "monitor/send_cm_data_list";
		} catch (Exception e) {
			logger.error("操作失败", e);
			return toAlertPage(model, e.getMessage());
		}
	}

	/**
	 * 查看页面
	 * @param model
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "/send_cm_data_get")
	public String get(Model model, String id) {
		try {
			SendCmData vo = cmDataService.get(id);
			String payload = vo.getPayload();
			String path = AppConst.CMDATA_STORED_DIR + File.separator + payload;
			File file = new File(path);
			if (file.exists()) {
				String payloadContent = FileUtils.readFileToString(file);
				vo.setPayloadContent(payloadContent);
			} else {
				model.addAttribute("payloadError", "数据报文文件[" + path + "]不存在");
			}
			boolean encryptFlag=false;
			boolean compressFlag=false;
			List<ProcessInfo> proes=XstreamUtil.toObject(Posthead.class, vo.getPosthead()).getProcesses().getProcess();
			if (proes!=null && !proes.isEmpty()) {
				String encrypt=proes.get(0).getEncrypt();
				String compress=proes.get(0).getCompress();
				if (encrypt.equals("1")) {
					encryptFlag=true;	
				}else{
					encryptFlag=false;
				}
				if (compress.equals("1")) {
					compressFlag=true;	
				}else{
					compressFlag=false;
				}
				
			}
			String routeLogXml = vo.getRoutelog();
			RouteLog routeLog = XstreamUtil.toObject(RouteLog.class,routeLogXml);
			model.addAttribute("netType", NodeInfoParam.NODE_NET_TYPE);
			model.addAttribute(DATA_KEY, vo);
			model.addAttribute("routeLog", routeLog);
			model.addAttribute("encrypt",encryptFlag);
			model.addAttribute("compress",compressFlag);
			return "monitor/send_cm_data_get";
		} catch (Exception e) {
			logger.error("操作失败", e);
			return toAlertPage(model, e.getMessage());
		}
	}

	
	/**
	 * 根据ID删除记录
	 * @param model
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "/send_cm_data_delete", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> delete(Model model, String id) {
		try {
			cmDataService.delete(id);
			return jsonSuccessResult("删除成功");
		} catch (Exception e) {
			logger.error("删除失败", e);
			return jsonFailResult("删除失败");
		}
	}

	/**
	 * 批量删除
	 * @param ids
	 * @return
	 */
	@RequestMapping(value = "/send_cm_data_deletes", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> deleteByIds(@RequestParam("ids") String ids) {
		String msg = "";
		try {
			msg = "删除成功";
			cmDataService.deleteBatchById(ids.split(","));
			return jsonSuccessResult(msg);
		} catch (Exception e) {
			msg = "批量删除失败";
			logger.error(msg, e);
			return jsonFailResult(msg);
		}
	}
	
	/**
	 * 获取子消息
	 * @param model
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "/send_cm_data_submsg")
	public String submsg(Model model, String id) {
		try {
			WhereCondition searchData = new WhereCondition();
			searchData.where().eq("pid", id);
			List<SendCmData> dataList = cmDataService.list(searchData);
			model.addAttribute("data_list", dataList);
		} catch (Exception e) {
			logger.error("获取自消息失败", e);
		}
		return "monitor/send_cm_data_submsg";
	}
	
	

	/**
	 * 下载消息体
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "/send_cm_data_download")
	public void download(HttpServletResponse response,String id) {
		try {
			SendCmData vo = cmDataService.get(id);
			String payload = vo.getPayload();
			String path = AppConst.CMDATA_STORED_DIR + File.separator + payload;
			File file = new File(path);
			if (file.exists()) {
				String nameToShow=null;
				//如果是sql类型，生成sql文件
				nameToShow=vo.getId()+".txt";
				downLoadFile(response, file, nameToShow);
			} else {
				logger.error("数据报文文件[" + path + "]不存在");
			}
		} catch (Exception e) {
			logger.error("操作失败", e);
		}
	}
	
	/**
	 * 刻盘
	 * @param model
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "/send_cm_data_carvedDiscs")
	public void carvedDiscs(HttpServletResponse response, String[] id) {
		try {
			File baseFile=tempFile(id);
			if (baseFile!=null) {
				String zipFile= baseFile.getAbsolutePath()+".zip";
				String showName=baseFile.getName()+"_结构化数据.zip";
				ZipUtil.compress(baseFile.getAbsolutePath(),zipFile, "gbk", "结构化数据压缩文件");
				downLoadFile(response, new File(zipFile), showName);
				for (String string : id) {
					SendCmData vo= cmDataService.get(string);
					if (vo.getCrossNet().equals("1")) {
						CmDataExchangeLifecycle service = (CmDataExchangeLifecycleImpl) CM.getBeanByName(AppIocBean.CM_DATA_EXCHANGE_LIFECYCLE_BEAN);
						service.carvedDiscs(vo);
					}
				}
			}
		} catch (Exception e) {
			
			logger.error("操作失败", e);
		}
	}
	
	
	public File tempFile(String[] id) throws IOException, ServiceException{
		String dataString=new SimpleDateFormat("yyyyMMDDHHmmss").format(new Date());
		File baseFile=new File("F:\\temp\\"+dataString);
		if (!baseFile.exists()) {
			baseFile.mkdirs();
		}
		for (String string : id) {
			File cmDataFile=new File(baseFile,string+".txt");
			SendCmData vo;
			
			vo = cmDataService.get(string);
			String payload = vo.getPayload();
			String path = AppConst.CMDATA_STORED_DIR + File.separator + payload;
			File file = new File(path);
			if (file.exists()) {
				String payloadContent = FileUtils.readFileToString(file);
				vo.setPayloadContent(payloadContent);
			} else {
				baseFile=null;
				break;
			}
		   JsonUtil.toJsonFile(cmDataFile, vo);
		}
		
		return baseFile;
	}
	

}
